#include <Windows.h>
#include "timer/RefCountTimer.h"
#include "timer/ProfilerManager.h"
#include <boost/format.hpp>

namespace timer
{


	RefCountTimer::RefCountTimer(const char *_FunctionSignature, const char *_FileName, const int &_LineNumber)
		:m_function_signature(_FunctionSignature), m_file_name(_FileName), m_line_number(_LineNumber),m_end(0),m_freq(0)
	{
		boost::format formater("%1% %2%");
		formater %_FileName %_LineNumber;
		this->m_key = formater.str();
		::QueryPerformanceCounter((PLARGE_INTEGER)&m_start);
	}

	RefCountTimer::~RefCountTimer( void )
	{
		::QueryPerformanceCounter((PLARGE_INTEGER)&m_end);
		::QueryPerformanceFrequency((PLARGE_INTEGER)&m_freq);

		__int64 diff = m_end - m_start;
		double time = double(diff)/double(m_freq);

		typedef ProfilerManager::ProfilerMap ProfilerMap;
		typedef ProfilerManager::ProfilerMapIterator ProfilerMapIterator;

		ProfilerMap &profiler_map = ProfilerManager::getInstance().m_profiler_map;
		ProfilerMapIterator iterator = profiler_map.find(m_key);

		if(iterator == profiler_map.end())
		{
			ProfilerInfo *info = new ProfilerInfo();
			info->FunctionSignature = m_function_signature;
			info->FileName = m_file_name;
			info->LineNumber = m_line_number;
			info->AvgFrequentInvocationTime = NULL;
			info->AvgInvocationTime = time;
			info->InvocationTimes = 1;
			info->LastTimeSignature = m_end;
			profiler_map[m_key] = info;

		}
		else
		{
			ProfilerInfo *info = profiler_map[m_key];
			info->AvgInvocationTime = (info->AvgInvocationTime + time)/2.0;
			info->InvocationTimes += 1;
			
			diff = m_end - info->LastTimeSignature;
			time = double(diff)/double(m_freq);
			info->LastTimeSignature = m_end;
			if(info->AvgFrequentInvocationTime != NULL)
			{
				info->AvgFrequentInvocationTime = (info->AvgFrequentInvocationTime + time)/2.0;
			}
			else
			{
				info->AvgFrequentInvocationTime = time;
			}
		}
	}

}